///\todo upgrade

//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#ifndef _BUOLA_IMAGE_ALGORITHM_STATISTICS_H_
#define _BUOLA_IMAGE_ALGORITHM_STATISTICS_H_

#include <buola/image/algorithm/detail/opencv.h>

namespace buola { namespace img {

//! \name statistics
//@{

template<typename tFormat,typename tScalar>
inline void min_max(const CView<tFormat> &pSrc,tScalar &pMin,tScalar &pMax)
{
    double lMin,lMax;
    cv::minMaxLoc(mat_wrap(pSrc),&lMin,&lMax);

    pMin=(tScalar)lMin;
    pMax=(tScalar)lMax;
}

template<typename tFormat,typename tScalar>
inline void min_max_loc(const CView<tFormat> &pSrc,CPoint_i &pMin,CPoint_i &pMax)
{
    double lMin,lMax;
    CvPoint lPointMin,lPointMax;

    cv::minMaxLoc(mat_wrap(pSrc),&lMin,&lMax,&lPointMin,&lPointMax);

    pMin=CPoint_i(lPointMin.x,lPointMin.y);
    pMax=CPoint_i(lPointMax.x,lPointMax.y);
}

template<typename tFormat>
inline double image_mean(const CView<tFormat> &pI)
{
    int lSum=0;

    for(int y=0;y<pI.Height();++y)
    {
        auto lIt=pI.RowBegin(y);

        for(int x=0;x<pI.Width();++x)
        {
            for(int c=0;c<tFormat::cChannels;++c)
                lSum+=(int)lIt[x][c];
        }
    }

    return (double)lSum/(double)(pI.Width()*pI.Height()*tFormat::cChannels);
}

template<typename tFormat>
inline double image_mean_square(const CView<tFormat> &pI)
{
    int64_t lSum=0;

    for(int y=0;y<pI.Height();++y)
    {
        auto lIt=pI.RowBegin(y);

        for(int x=0;x<pI.Width();++x)
        {
            for(int c=0;c<tFormat::cChannels;++c)
                lSum+=(int64_t)lIt[x][c]*(int64_t)lIt[x][c];
        }
    }

    return (double)lSum/(double)(pI.Width()*pI.Height()*tFormat::cChannels);
}

inline CPoint_d center_of_mass(const CView_gray8 &pI)
{
    int lXSum=0,lYSum=0;
    int lCount=0;

    for(int y=0;y<pI.Height();++y)
    {
        auto lIt=pI.Row(y).begin();

        for(int x=0;x<pI.Width();++x)
        {
            if(lIt[x])
            {
                lXSum+=x;
                lYSum+=y;
                lCount++;
            }
        }
    }

    return CPoint_d((double)lXSum/(double)lCount,(double)lYSum/(double)lCount);
}

float image_max(const CView_gray32f &pImage);
float image_min(const CView_gray32f &pImage);
void image_minmax(const CView_gray32f &pImage,float &pMin,float &pMax);
float local_max_mean(const CView_gray32f &pImage,float pAbsMax);

//@}
    
/*namespace image*/ } /*namespace buola*/ }

#endif
